<!-- 数字输入框 -->
<template>
    <div class="si-input-number">
        <div v-if="label" class="input-number-label" @mousedown.stop="onResizable">
            {{ label }}
        </div>
        <div class="input-number-content">
            <div class="resize-handle" @mousedown.stop="onResizable"></div>
            <el-input-number
                v-model="currentValue"
                :min="min"
                :max="max"
                :step="step"
                size="default"
                controls-position="right"
            />
        </div>
    </div>
</template>

<script>
import { defineComponent, toRefs, computed } from 'vue'
export default defineComponent({
    name: 'SiInputNumber',
    props: {
        modelValue: {
            type: [Number, String]
        },
        // 标题
        label: {
            type: String,
            default: ''
        },
        // 单位
        unit: {
            type: String
        },
        // 设置计数器允许的最小值
        min: {
            type: Number,
            default: -Infinity
        },
        // 设置计数器允许的最大值
        max: {
            type: Number,
            default: Infinity
        },
        // 计数器步长
        step: {
            type: Number,
            default: 1
        }
    },
    emits: ['update:modelValue'],
    setup(props, { emit }) {
        const { modelValue, label, unit, min, max, step } = toRefs(props)

        const currentValue = computed({
            get: () => Object.prototype.toString.call(modelValue.value) === '[object Number]' ? modelValue.value : parseInt(modelValue.value),
            set: val => {
                let value = val
                if (unit.value !== undefined) {
                    value = `${value}${unit.value}`
                } else if (Object.prototype.toString.call(modelValue.value) === '[object String]') {
                    value = `${value}`
                }
                emit('update:modelValue', value)
            }
        })

        const onResizable = e => {
            // 鼠标开始点击位置
            const { clientX: mouseX } = e
            const oldValue = currentValue.value || 0
            document.onmousemove = event => {
                const offsetX = parseInt(event.pageX - mouseX) * step.value
                let newValue = oldValue + offsetX
                if (newValue <= min.value) newValue = min.value
                if (newValue >= max.value) newValue = max.value
                currentValue.value = newValue
            }
            document.onmouseup = () => {
                document.onmousemove = null
                document.onmouseup = null
            }
        }

        return {
            currentValue,
            label,
            min,
            max,
            step,

            onResizable
        }
    }
})
</script>

<style lang="less" scoped>
.si-input-number {
    display: inline-flex;
    align-items: center;
    position: relative;
    & + .si-input-number {
        margin-left: 12px;
    }
    .input-number-label {
        color: var(--edit-text-color-regular);
        padding-right: 8px;
        cursor: e-resize;
    }
    .input-number-content {
        position: relative;
        .resize-handle {
            position: absolute;
            left: 0;
            top: 0;
            bottom: 0;
            width: 5px;
            cursor: e-resize;
            z-index: 2;
        }
        ::v-deep(.el-input-number) {
            width: 64px;
            .el-input__inner {
                text-align: left;
            }
            .el-input-number__decrease {
                width: 22px;
            }
            .el-input-number__increase {
                width: 22px;
            }
            .el-input__wrapper {
                padding-left: 10px;
                padding-right: 28px;
            }
        }
    }
}
</style>